package com.expert.miniapp.controller;

import com.expert.miniapp.dao.Demand;
import com.expert.miniapp.dto.DemandDTO;
import com.expert.miniapp.dto.DemandHistoryDTO;
import com.expert.miniapp.dto.ResultDTO;
import com.expert.miniapp.service.DemandService;
import com.github.pagehelper.PageInfo;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * DemandController - 需求控制器
 * 提供需求的POST/PUT/GET接口
 *
 * @author System
 * @since 2025-10-19
 */
@RestController
@RequestMapping("/api/demands")
@CrossOrigin(origins = "*")
public class DemandController {

    private static final Logger logger = LoggerFactory.getLogger(DemandController.class);

    @Autowired
    private DemandService demandService;

    /**
     * 创建新需求（状态为DRAFT）
     *
     * @param demandDTO     需求DTO对象
     * @param bindingResult 验证结果
     * @return 统一响应结构，包含创建的需求对象
     */
    @PostMapping(produces = "application/json;charset=UTF-8")
    public ResultDTO<Demand> createDemand(
            @Valid @RequestBody DemandDTO demandDTO,
            BindingResult bindingResult
    ) {
        logger.info("接收到创建需求请求: userId={}", demandDTO.getUserId());

        try {
            // 参数验证
            if (bindingResult.hasErrors()) {
                String errorMsg = bindingResult.getAllErrors().stream()
                        .map(error -> error.getDefaultMessage())
                        .collect(Collectors.joining("; "));
                logger.warn("参数验证失败: {}", errorMsg);
                return ResultDTO.error("参数验证失败：" + errorMsg);
            }

            // 创建需求
            Demand demand = demandService.createDemand(demandDTO);

            logger.info("需求创建成功: demandId={}", demand.getDemandId());

            return ResultDTO.success(demand);

        } catch (Exception e) {
            logger.error("创建需求失败", e);
            return ResultDTO.error("创建需求失败：" + e.getMessage());
        }
    }

    /**
     * 更新需求信息
     *
     * @param demandId      需求ID
     * @param demandDTO     需求DTO对象
     * @param bindingResult 验证结果
     * @return 统一响应结构，包含更新后的需求对象
     */
    @PutMapping(value = "/{demandId}", produces = "application/json;charset=UTF-8")
    public ResultDTO<Demand> updateDemand(
            @PathVariable String demandId,
            @Valid @RequestBody DemandDTO demandDTO,
            BindingResult bindingResult
    ) {
        logger.info("接收到更新需求请求: demandId={}", demandId);

        try {
            // 参数校验
            if (demandId == null || demandId.trim().isEmpty()) {
                logger.warn("需求ID参数为空");
                return ResultDTO.error("需求ID不能为空");
            }

            if (bindingResult.hasErrors()) {
                String errorMsg = bindingResult.getAllErrors().stream()
                        .map(error -> error.getDefaultMessage())
                        .collect(Collectors.joining("; "));
                logger.warn("参数验证失败: {}", errorMsg);
                return ResultDTO.error("参数验证失败：" + errorMsg);
            }

            // 更新需求
            Demand demand = demandService.updateDemand(demandId, demandDTO);

            logger.info("需求更新成功: demandId={}", demandId);

            return ResultDTO.success(demand);

        } catch (RuntimeException e) {
            logger.error("更新需求失败: demandId={}", demandId, e);
            return ResultDTO.error(e.getMessage());
        } catch (Exception e) {
            logger.error("更新需求失败: demandId={}", demandId, e);
            return ResultDTO.error("更新需求失败：" + e.getMessage());
        }
    }

    /**
     * 提交需求（状态从DRAFT变更为SUBMITTED）
     *
     * @param demandId 需求ID
     * @return 统一响应结构，包含提交后的需求对象
     */
    @PostMapping(value = "/{demandId}/submit", produces = "application/json;charset=UTF-8")
    public ResultDTO<Demand> submitDemand(@PathVariable String demandId) {
        logger.info("接收到提交需求请求: demandId={}", demandId);

        try {
            // 参数校验
            if (demandId == null || demandId.trim().isEmpty()) {
                logger.warn("需求ID参数为空");
                return ResultDTO.error("需求ID不能为空");
            }

            // 提交需求
            Demand demand = demandService.submitDemand(demandId);

            logger.info("需求提交成功: demandId={}", demandId);

            return ResultDTO.success(demand);

        } catch (RuntimeException e) {
            logger.error("提交需求失败: demandId={}", demandId, e);
            return ResultDTO.error(e.getMessage());
        } catch (Exception e) {
            logger.error("提交需求失败: demandId={}", demandId, e);
            return ResultDTO.error("提交需求失败：" + e.getMessage());
        }
    }

    /**
     * 获取需求详情
     *
     * @param demandId 需求ID
     * @return 统一响应结构，包含需求详情
     */
    @GetMapping(value = "/{demandId}", produces = "application/json;charset=UTF-8")
    public ResultDTO<Demand> getDemandDetail(@PathVariable String demandId) {
        logger.info("接收到获取需求详情请求: demandId={}", demandId);

        try {
            // 参数校验
            if (demandId == null || demandId.trim().isEmpty()) {
                logger.warn("需求ID参数为空");
                return ResultDTO.error("需求ID不能为空");
            }

            // 查询需求详情
            Demand demand = demandService.getDemandById(demandId);

            if (demand == null) {
                logger.warn("需求不存在: demandId={}", demandId);
                return ResultDTO.error("需求不存在");
            }

            logger.info("需求详情查询成功: demandId={}", demandId);

            return ResultDTO.success(demand);

        } catch (Exception e) {
            logger.error("获取需求详情失败: demandId={}", demandId, e);
            return ResultDTO.error("获取需求详情失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户的需求列表
     *
     * @param userId 用户ID
     * @return 统一响应结构，包含需求列表
     */
    @GetMapping(value = "/user/{userId}", produces = "application/json;charset=UTF-8")
    public ResultDTO<Map<String, Object>> getUserDemands(
            @PathVariable String userId,
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
    ) {
        logger.info("收到获取用户需求列表请求: userId={}, pageNum={}, pageSize={}", userId, pageNum, pageSize);

        try {
            // 参数校验
            if (userId == null || userId.trim().isEmpty()) {
                logger.warn("用户ID为空");
                return ResultDTO.error("用户ID不能为空");
            }

            if (pageNum < 1) {
                logger.warn("页码不合法: pageNum={}", pageNum);
                return ResultDTO.error("页码必须大于0");
            }

            if (pageSize < 1 || pageSize > 100) {
                logger.warn("每页大小不合法: pageSize={}", pageSize);
                return ResultDTO.error("每页大小需要在1-100之间");
            }

            // 查询用户需求列表
            PageInfo<Demand> pageInfo = demandService.getDemandsByUserId(userId, pageNum, pageSize);
            Map<String, Object> payload = new LinkedHashMap<>();
            payload.put("total", pageInfo.getTotal());
            payload.put("pageNum", pageInfo.getPageNum());
            payload.put("pageSize", pageInfo.getPageSize());
            payload.put("pages", pageInfo.getPages());
            payload.put("list", pageInfo.getList());

            logger.info("用户需求列表查询成功: total={}, currentSize={}", pageInfo.getTotal(), pageInfo.getList().size());

            return ResultDTO.success(payload);

        } catch (Exception e) {
            logger.error("获取用户需求列表失败: userId={}", userId, e);
            return ResultDTO.error("获取用户需求列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有需求列表
     *
     * @return 统一响应结构，包含所有需求列表
     */
    @GetMapping(produces = "application/json;charset=UTF-8")
    public ResultDTO<List<Demand>> getAllDemands() {
        logger.info("接收到获取所有需求列表请求");

        try {
            // 查询所有需求
            List<Demand> demands = demandService.getAllDemands();

            logger.info("需求列表查询成功，共 {} 条记录", demands.size());

            return ResultDTO.success(demands);

        } catch (Exception e) {
            logger.error("获取所有需求列表失败", e);
            return ResultDTO.error("获取所有需求列表失败：" + e.getMessage());
        }
    }

    /**
     * 删除需求（级联删除所有推荐记录）
     *
     * @param demandId 需求ID
     * @return 统一响应结构，包含删除结果信息
     */
    @DeleteMapping(value = "/{demandId}", produces = "application/json;charset=UTF-8")
    public ResultDTO<Map<String, Integer>> deleteDemand(@PathVariable String demandId) {
        logger.info("接收到删除需求请求: demandId={}", demandId);

        try {
            // 参数校验
            if (demandId == null || demandId.trim().isEmpty()) {
                logger.warn("需求ID参数为空");
                return ResultDTO.error("需求ID不能为空");
            }

            // 级联删除需求
            Map<String, Integer> result = demandService.deleteByIdCascade(demandId);

            logger.info("需求删除成功: 需求={}, 推荐={}, 明细={}",
                    result.get("demandDeleted"),
                    result.get("recommendationsDeleted"),
                    result.get("itemsDeleted"));

            return ResultDTO.success(result);

        } catch (IllegalArgumentException e) {
            logger.error("删除需求失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());

        } catch (Exception e) {
            logger.error("删除需求失败: demandId={}", demandId, e);
            return ResultDTO.error("删除需求失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户需求历史记录（带分页和时间筛选）
     *
     * @param userId    用户ID
     * @param pageNum   页码（默认1）
     * @param pageSize  每页大小（默认10）
     * @param startTime 开始时间（可选，格式：yyyy-MM-dd HH:mm:ss）
     * @param endTime   结束时间（可选，格式：yyyy-MM-dd HH:mm:ss）
     * @return 统一响应结构，包含分页的需求历史列表
     */
    @GetMapping(value = "/user/{userId}/history", produces = "application/json;charset=UTF-8")
    public ResultDTO<PageInfo<DemandHistoryDTO>> getUserDemandsHistory(
            @PathVariable String userId,
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(value = "startTime", required = false)
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam(value = "endTime", required = false)
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime
    ) {
        logger.info("接收到获取用户需求历史请求: userId={}, pageNum={}, pageSize={}, startTime={}, endTime={}",
                userId, pageNum, pageSize, startTime, endTime);

        try {
            // 参数校验
            if (userId == null || userId.trim().isEmpty()) {
                logger.warn("用户ID参数为空");
                return ResultDTO.error("用户ID不能为空");
            }

            if (pageNum < 1) {
                logger.warn("页码参数非法: pageNum={}", pageNum);
                return ResultDTO.error("页码必须大于0");
            }

            if (pageSize < 1 || pageSize > 100) {
                logger.warn("每页大小参数非法: pageSize={}", pageSize);
                return ResultDTO.error("每页大小必须在1-100之间");
            }

            // 查询用户需求历史
            PageInfo<DemandHistoryDTO> pageInfo = demandService.getUserDemandsWithPagination(
                    userId, pageNum, pageSize, startTime, endTime
            );

            logger.info("用户需求历史查询成功，共 {} 条记录，当前页 {} 条",
                    pageInfo.getTotal(), pageInfo.getList().size());

            return ResultDTO.success(pageInfo);

        } catch (Exception e) {
            logger.error("获取用户需求历史失败: userId={}", userId, e);
            return ResultDTO.error("获取用户需求历史失败：" + e.getMessage());
        }
    }

    /**
     * 获取需求完整详情（包含需求信息和推荐记录）
     *
     * @param demandId 需求ID
     * @return 统一响应结构，包含需求完整信息（需求+推荐）
     */
    @GetMapping(value = "/{demandId}/complete", produces = "application/json;charset=UTF-8")
    public ResultDTO<Map<String, Object>> getDemandComplete(@PathVariable String demandId) {
        logger.info("接收到获取需求完整详情请求: demandId={}", demandId);

        try {
            // 参数校验
            if (demandId == null || demandId.trim().isEmpty()) {
                logger.warn("需求ID参数为空");
                return ResultDTO.error("需求ID不能为空");
            }

            // 查询需求完整详情
            Map<String, Object> result = demandService.getDemandComplete(demandId);

            logger.info("需求完整详情查询成功: demandId={}", demandId);

            return ResultDTO.success(result);

        } catch (IllegalArgumentException e) {
            logger.error("获取需求完整详情失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());

        } catch (Exception e) {
            logger.error("获取需求完整详情失败: demandId={}", demandId, e);
            return ResultDTO.error("获取需求完整详情失败：" + e.getMessage());
        }
    }

    /**
     * 重新生成需求的AI摘要
     *
     * @param demandId 需求ID
     * @return 统一响应结构，包含更新后的需求对象
     */
    @PostMapping(value = "/{demandId}/regenerate-summary", produces = "application/json;charset=UTF-8")
    public ResultDTO<Demand> regenerateDemandSummary(@PathVariable String demandId) {
        logger.info("接收到重新生成摘要请求: demandId={}", demandId);

        try {
            // 参数校验
            if (demandId == null || demandId.trim().isEmpty()) {
                logger.warn("需求ID参数为空");
                return ResultDTO.error("需求ID不能为空");
            }

            // 重新生成摘要
            Demand demand = demandService.regenerateDemandSummary(demandId);

            logger.info("摘要重新生成成功: demandId={}", demandId);

            return ResultDTO.success(demand);

        } catch (IllegalArgumentException e) {
            logger.error("重新生成摘要失败: {}", e.getMessage());
            return ResultDTO.error(e.getMessage());

        } catch (Exception e) {
            logger.error("重新生成摘要失败: demandId={}", demandId, e);
            return ResultDTO.error("重新生成摘要失败：" + e.getMessage());
        }
    }
}


